package com.codepilot.server.service.impl;

import java.util.HashMap;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import com.codepilot.server.model.dto.UserDTO;
import com.codepilot.server.model.entity.User;
import com.codepilot.server.model.exception.enums.GlobalErrorCodeConstants;
import com.codepilot.server.mapper.UserMapper;
import com.codepilot.server.service.AuthenticateService;
import com.codepilot.server.utils.JwtUtil;
import com.codepilot.server.utils.RedisCache;
import com.codepilot.server.utils.TimeUtil;
import com.codepilot.server.model.vo.CommonResult;
import com.codepilot.server.model.vo.LoginUserVO;
import com.codepilot.server.model.vo.RegisterUserVO;

@Service
public class AuthenticateServiceImpl implements AuthenticateService {

    @Autowired
    private PasswordEncoder passwordEncoder;

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserMapper userMapper;

    @Autowired
    private JwtUtil jwtUtil;

    @Autowired
    private RedisCache redisCache;

    @Autowired
    private TimeUtil timeUtil;

    @Override
    public CommonResult<?> register(RegisterUserVO registerUserVO) {
        User foundUser = userMapper.findByUsername(registerUserVO.getUsername());

        if (foundUser != null) {
            return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST);
        }

        User user = new User(registerUserVO);
        user.setPassword(passwordEncoder.encode(user.getPassword()));
        user.setCharacter("user");
        user.setStatus("normal");
        user.setRegisterTime(timeUtil.getCurrentDatetime());

        try {
            userMapper.insert(user);
        } catch (Exception e) {
            System.out.println(e.toString());
            return CommonResult.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR);
        }

        return CommonResult.success("注册成功");
    }

    @Override
    public CommonResult<?> login(LoginUserVO loginUserVO) {
        UsernamePasswordAuthenticationToken authenticationToken = new UsernamePasswordAuthenticationToken(
                loginUserVO.getUsername(), loginUserVO.getPassword());
        Authentication authentication = authenticationManager.authenticate(authenticationToken);

        if (authentication == null) {
            return CommonResult.error(GlobalErrorCodeConstants.BAD_REQUEST);
        }

        UserDTO loginUser = (UserDTO) authentication.getPrincipal();

        User user = loginUser.getUser();
        user.setLastLoginTime(timeUtil.getCurrentDatetime());
        String token = jwtUtil.generateAccessToken(user.getUsername());
        try {
            userMapper.updateTime(user);
        } catch (Exception e) {
            return CommonResult.error(GlobalErrorCodeConstants.INTERNAL_SERVER_ERROR);
        }

        // 将loginUser存入redis缓存
        redisCache.setCacheObject("login:"+user.getUsername(), loginUser);

        // 将token存入response返回
        HashMap<String, String> map = new HashMap<>();
        map.put("token", token);
        return CommonResult.success(map);
    }

}
